package com.CampaignManager.client;

import com.CampaignManager.shared.JobDTO;
import com.CampaignManager.shared.PlayerDTO;
import com.CampaignManager.shared.UnitDTO;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.Widget;

public class CharacterScreen extends Composite {

	private static CharacterScreenUiBinder uiBinder = GWT
			.create(CharacterScreenUiBinder.class);

	interface CharacterScreenUiBinder extends UiBinder<Widget, CharacterScreen> {
	}

	private CampaignManager mainForm = null;
	private PlayerDTO playerInfo = null;
	//private boolean admin = false;
	
	public CharacterScreen(final CampaignManager mainForm, final PlayerDTO playerInfo, boolean admin) {

		this.mainForm = mainForm;
		this.playerInfo = playerInfo;
		//this.admin = admin;
		
		initWidget(uiBinder.createAndBindUi(this));
		
		if (admin) {
			this.btnAddLevel.setVisible(true);
			this.btnAddEspionage.setVisible(true);
			this.btnAddNP.setVisible(true);
		}
		
		BindFields();
		
		if (playerInfo.isCurrentPlayer()) {
			this.txtDescription.setEnabled(true);
			this.txtDescription.addChangeHandler(new ChangeHandler() {				
				@Override
				public void onChange(ChangeEvent event) {
					if (txtDescription.getText().length() >= 500) {
						Window.alert("Messages have to be less than 500 characters. You're at " + txtDescription.getText().length());
						return;
					}	
					mainForm.campaignService.UpdateBio(txtDescription.getText(), new AsyncCallback<Void>() {						
						@Override
						public void onSuccess(Void result) {
							//nothing needed.
						}
						
						@Override
						public void onFailure(Throwable caught) {
							mainForm.handleError(caught);
						}
					});
				}
			});
		}
	}
	
	@UiField
	Label lblCharName;
	@UiField
	Label lblLevel;
	@UiField
	TextArea txtDescription;
	@UiField
	Label lblPlayedBy;
	
	@UiField
	FlexTable unitTable;
	
	@UiField
	FlexTable jobsTable;
	
	private void BindFields() {
		this.lblCharName.setText(playerInfo.getCharacterName());
		this.lblLevel.setText("Journeyman Warcaster");
		this.txtDescription.setText(playerInfo.getCharacterDescription());
		this.lblPlayedBy.setText("Played by: "+playerInfo.getNickName()+" <"+playerInfo.getEmailAddress()+">");
		
		SetupLevelTable();
		
		SetupUnitTable();
		for (UnitDTO u : playerInfo.getUnits()) {
			DisplayUnitRow(u);
		}
		final int row = unitTable.getRowCount();
		unitTable.getRowFormatter().addStyleName(row, "watchListHeader");
		unitTable.setText(row, 1, "Total");
		unitTable.getCellFormatter().addStyleName(row, 2, "watchListNumericColumn");
		unitTable.setText(row, 2, playerInfo.getArmySize().toString());
		unitTable.getCellFormatter().addStyleName(row, 2, "watchListNumericColumn");
		
		DisplayJobs((JobDTO[]) playerInfo.getJobs().toArray(new JobDTO[0]));
	}
	
	@UiField
	FlexTable levelTable;
	
	@UiField
	Button btnAddLevel;
	@UiHandler("btnAddLevel")
	void btnAddLevelClick(ClickEvent event) {
		btnAddLevel.setEnabled(false);
		mainForm.campaignService.IncrementStat(playerInfo.getEmailAddress(), PlayerDTO.Stat.Level, new AsyncCallback<Void>() {
			@Override
			public void onSuccess(Void result) {
				playerInfo.setLevel(playerInfo.getLevel()+1);
				BindFields();
				btnAddLevel.setEnabled(true);
			}			
			@Override
			public void onFailure(Throwable caught) {
				mainForm.handleError(caught);
			}
		});
	}
	
	@UiField
	Button btnAddEspionage;
	@UiHandler("btnAddEspionage")
	void btnAddEspionageClick(ClickEvent event) {
		btnAddEspionage.setEnabled(false);
		mainForm.campaignService.IncrementStat(playerInfo.getEmailAddress(), PlayerDTO.Stat.EspionageLevel, new AsyncCallback<Void>() {
			@Override
			public void onSuccess(Void result) {
				playerInfo.setEspionageLevel(playerInfo.getEspionageLevel()+1);
				BindFields();
				btnAddEspionage.setEnabled(true);
			}			
			@Override
			public void onFailure(Throwable caught) {
				mainForm.handleError(caught);
			}
		});
	}
	
	@UiField
	Button btnAddNP;
	@UiHandler("btnAddNP")
	void btnAddNPClick(ClickEvent event) {
		btnAddNP.setEnabled(false);
		mainForm.campaignService.IncrementStat(playerInfo.getEmailAddress(), PlayerDTO.Stat.NarrationPoints, new AsyncCallback<Void>() {
			@Override
			public void onSuccess(Void result) {
				playerInfo.setNarrationPoints(playerInfo.getNarrationPoints()+1);
				BindFields();
				btnAddNP.setEnabled(true);
			}			
			@Override
			public void onFailure(Throwable caught) {
				mainForm.handleError(caught);
			}
		});
	}

	private void SetupLevelTable() {
		
		levelTable.removeAllRows();
		
		levelTable.setText(0, 0, "Attibute");
		levelTable.setText(0, 1, "Value");
		
		levelTable.getRowFormatter().addStyleName(0, "watchListHeader");
		levelTable.addStyleName("watchList");
		
		levelTable.setText(1, 0, "Leadership Level");
		levelTable.setText(1, 1, playerInfo.getLevel().toString());
		
		levelTable.setText(2, 0, "Max Army Size");
		levelTable.setText(2, 1, PlayerDTO.getPointLimit(playerInfo.getLevel()).toString());
		
		levelTable.setText(3, 0, "Espionage Level");
		levelTable.setText(3, 1, playerInfo.getEspionageLevel().toString());
		
		levelTable.setText(4, 0, "Narration Points");
		levelTable.setText(4, 1, playerInfo.getNarrationPoints().toString());
		
	}
	
	private void SetupUnitTable() {
		
		unitTable.getCellFormatter().setWidth(0, 0, "50");
		
		unitTable.setText(0, 1, "Unit Name");
		unitTable.setText(0, 2, "Current Value");
		
		unitTable.getRowFormatter().addStyleName(0, "watchListHeader");
		unitTable.addStyleName("watchList");
		unitTable.getCellFormatter().addStyleName(0, 2, "watchListNumericColumn");
	}
	public void DisplayUnitRow(final UnitDTO unit) {
		final int row = unitTable.getRowCount();
		DisplayUnitRow(unit, row);
	}
	public void DisplayUnitRow(final UnitDTO unit, final int row) {
		
		Anchor nameLink = new Anchor(unit.getName());
		nameLink.setHref("http://battlecollege.wikispaces.com/" + unit.getUnitType().getHref());
		nameLink.setTarget("_blank");
		unitTable.setWidget(row, 1, nameLink);
						
		if (unit.getPoints() >= unit.getUnitType().getMaxPoints() && unit.getUnitType().getMaxPoints() > 0) {
			unitTable.setText(row, 2, unit.getUnitType().getMaxPoints().toString());
		} else if (unit.getPoints() >= unit.getUnitType().getMinPoints()) {
			unitTable.setText(row, 2, unit.getUnitType().getMinPoints().toString());
		} else {
			unitTable.setText(row, 2, "0");
		}
		unitTable.getCellFormatter().addStyleName(row, 2, "watchListNumericColumn");		
	}
	
	private void DisplayJobs(JobDTO[] jobs) {
		
		jobsTable.removeAllRows();
				
		jobsTable.setText(0, 1, "Status");
		jobsTable.setText(0, 2, "Job");
		jobsTable.setText(0, 4, "Reward");
		
		jobsTable.getRowFormatter().addStyleName(0, "watchListHeader");
		jobsTable.addStyleName("watchList");
		jobsTable.getCellFormatter().addStyleName(0, 4, "watchListNumericColumn");
		
		for (JobDTO job : jobs) {
			DisplayJobRow(job);
		}
	}	
	public void DisplayJobRow(final JobDTO job) {
		final int row = jobsTable.getRowCount();
		DisplayJobRow(job, row);
	}
	public void DisplayJobRow(final JobDTO job, final int row) {
						
		jobsTable.setText(row, 1, job.getStatus());
		
		Anchor nameLink = new Anchor(job.getJobDescription());
		nameLink.setHref("http://groups.google.com/groups?threadm="+job.getStoryMessageID());
		nameLink.setTarget("_blank");
		jobsTable.setWidget(row, 2, nameLink);
		
		jobsTable.setText(row, 4, job.getReward().toString());
		jobsTable.getCellFormatter().addStyleName(row, 4, "watchListNumericColumn");
	}
	
	
}
